package com.chpro.freemarker;

import java.io.FileWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.sql.DataSource;

import org.apache.commons.configuration.CompositeConfiguration;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;
import com.chpro.freemarker.model.EntityAttribute;
import com.chpro.freemarker.util.HumpColumn;
import com.chpro.freemarker.util.LowerFirstCharacter;
import com.chpro.freemarker.util.StringUtils;
import com.chpro.freemarker.util.UpperFirstCharacter;
import com.chpro.jdbc.MyJdbc;
import com.chpro.jdbc.SqlServerColumnMapping;
import com.chpro.jdbc.SqlServerJdbc;
import com.chpro.jdbc.DBUtil;

import freemarker.template.Configuration;
import freemarker.template.SimpleHash;
import freemarker.template.Template;

/**
 * hibernate+spring+springMVC 风格版的自动生成
 * @author Administrator
 *
 */
public class JdbcClassPathPropertiesApplication implements ApplicationContext {

	/**
	 * 输出的包名
	 */
	private String outputPackageName;
	
	/**
	 * 输出的路径名
	 */
	private String outputFilePath;
	
	private static Configuration cfg;
	
	static MyJdbc myJdbc ; 
	
	public JdbcClassPathPropertiesApplication(){
		//初始化 包名 和输出的路径名
		CompositeConfiguration config = new CompositeConfiguration();
		try {
			config.addConfiguration(new PropertiesConfiguration("freemarker_config.properties"));
		} catch (ConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		outputPackageName = config.getString("output_package_name");
		outputFilePath = config.getString("output_file_path");
	}
	
	static{
		//初始化 freemarker 配置
		cfg = new Configuration();
		cfg.setClassForTemplateLoading(JdbcClassPathPropertiesApplication.class,"/resources");
		cfg.setSharedVariable("upperFC", new UpperFirstCharacter());//添加一个"宏"共享变量用来将属性名首字母大写
		cfg.setSharedVariable("lowerFC", new LowerFirstCharacter());//添加一个"宏"共享变量用来将属性名首字母小写
		cfg.setSharedVariable("humpColumn", new HumpColumn());//添加一个"宏"共享变量用来将属性名 变成驼峰标识
		
		//初始化jcbc 配置信息
		SqlServerJdbc sqlServerJdbc = new SqlServerJdbc();
		sqlServerJdbc.setJdbcTemplate(DBUtil.getJdbcTemplate());
		myJdbc = sqlServerJdbc;
		
	}
	
	public boolean buildEntity(String tableName)throws Exception {
		
		List<EntityAttribute> entityAttributeList = new ArrayList<EntityAttribute>();	
		
		List<Map<String,Object>> result = myJdbc.findColumns(tableName);
		
		String pk = myJdbc.findPropertyKey(tableName);	//根据表名得到主键
		
		for(Map<String,Object> map:result){
			EntityAttribute entityAttribute = new EntityAttribute();
			entityAttribute.setName(String.valueOf(map.get("column_name")));
			entityAttribute.setType(SqlServerColumnMapping.getValue(String.valueOf(map.get("data_type"))));
			entityAttribute.setIsPK(pk.equals(map.get("column_name"))?"true":"false");	//如果是主键则返回true 否则返回false
			entityAttributeList.add(entityAttribute);
		}
		
		//生成类时把tableName转换驼峰标识的类名
		String entityName = StringUtils.toHump(tableName);
		
		SimpleHash root = new SimpleHash();
		root.put("tableName", tableName);
		root.put("entityName", entityName);
		root.put("entityAttributeList", entityAttributeList);
		root.put("outputPackageName", outputPackageName);

        
        // Get the templat object
        Template t = cfg.getTemplate("hibernate_springmvc_entity.ftl");
        
        Writer out = new FileWriter(outputFilePath+entityName+".java");	//输出目录
        t.process(root, out);
        System.out.println("entity生成成功!");
		return true;
	}

	public boolean buildDao(String entityName)throws Exception {
		//设置变量
		SimpleHash root = new SimpleHash();
		root.put("tableName", entityName);
		root.put("outputPackageName", outputPackageName);
		
		//指定模版路径
		Template t = cfg.getTemplate("hibernate_springmvc_dao.ftl");
        
		//指定输出路径
        Writer out = new FileWriter(outputFilePath+entityName+"Dao.java");	//输出目录
        t.process(root, out);
        System.out.println("Dao生成成功!");
		return true;
	}

	public boolean buildDaoImpl(String entityName)throws Exception {
		//设置变量
		SimpleHash root = new SimpleHash();
		root.put("entityName", entityName);
		root.put("outputPackageName", outputPackageName);
		
		//指定模版路径
		Template t = cfg.getTemplate("hibernate_springmvc_daoImpl.ftl");
        
		//指定输出路径
        Writer out = new FileWriter(outputFilePath+entityName+"DaoImpl.java");	//输出目录
        t.process(root, out);
        System.out.println("DaoImpl生成成功!");
		return true;
	}

	public boolean buildService(String entityName)throws Exception {
		//设置变量
		SimpleHash root = new SimpleHash();
		root.put("entityName", entityName);
		root.put("outputPackageName", outputPackageName);
		
		//指定模版路径
		Template t = cfg.getTemplate("hibernate_springmvc_service.ftl");
        
		//指定输出路径
        Writer out = new FileWriter(outputFilePath+entityName+"Service.java");	//输出目录
        t.process(root, out);
        System.out.println("Service生成成功!");
		return true;
	}

	public boolean buildServiceImpl(String entityName)throws Exception {
		//设置变量
		SimpleHash root = new SimpleHash();
		root.put("entityName", entityName);
		root.put("outputPackageName", outputPackageName);
		
		//指定模版路径
		Template t = cfg.getTemplate("hibernate_springmvc_serviceImpl.ftl");
        
		//指定输出路径
        Writer out = new FileWriter(outputFilePath+entityName+"ServiceImpl.java");	//输出目录
        t.process(root, out);
        System.out.println("ServiceImpl生成成功!");
		return true;
	}

	public boolean buildController(String entityName)throws Exception {
		//设置变量
		SimpleHash root = new SimpleHash();
		root.put("entityName", entityName);
		root.put("outputPackageName", outputPackageName);
		
		//指定模版路径
		Template t = cfg.getTemplate("hibernate_springmvc_controller.ftl");
        
		//指定输出路径
        Writer out = new FileWriter(outputFilePath+entityName+"Controller.java");	//输出目录
        t.process(root, out);
        System.out.println("Controller生成成功!");
		return true;
	}

	public boolean buildMVC(String tableName) throws Exception {
		buildEntity(tableName);
		
		String entityName = StringUtils.toHump(tableName);;	//tableName 转换 entityName
		
		buildDao(entityName);
		buildDaoImpl(entityName);
		buildService(entityName);
		buildServiceImpl(entityName);
		buildController(entityName);
		
		return true;
	}

	public String getOutputPackageName() {
		return outputPackageName;
	}

	public void setOutputPackageName(String outputPackageName) {
		this.outputPackageName = outputPackageName;
	}

	public String getOutputFilePath() {
		return outputFilePath;
	}

	public void setOutputFilePath(String outputFilePath) {
		this.outputFilePath = outputFilePath;
	}

	
}
